package durst.data.json;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import com.sdicons.json.mapper.JSONMapper;
import com.sdicons.json.mapper.MapperException;
import com.sdicons.json.mapper.helper.SimpleMapperHelper;
import com.sdicons.json.model.JSONArray;
import com.sdicons.json.model.JSONBoolean;
import com.sdicons.json.model.JSONObject;
import com.sdicons.json.model.JSONValue;

import durst.data.Event;
import durst.data.FileAccess;
import durst.data.Invite;
import durst.data.dao.DaoFactory;

public class EventJSONHelper implements SimpleMapperHelper {
	private static SimpleDateFormat shortFormat = new SimpleDateFormat("hh:mma");
	private static SimpleDateFormat longFormat = new SimpleDateFormat("MM/dd hh:mma");
	private static SimpleDateFormat protoFormat = new SimpleDateFormat("MM-dd-yyyy hh:mmaa");

	@Override
	public Class<Event> getHelpedClass() {
		return Event.class;
	}

	@Override
	public JSONValue toJSON(Object aPojo) throws MapperException {
		if (aPojo instanceof Event && aPojo != null) {
			Event event = (Event) aPojo;

			if (event.getDescription() == null) {
				try {
					DaoFactory.getInstance().createDao(Event.class).refresh(event);
				}
				catch (SQLException e) {
					throw new MapperException("could not refresh Event object from DB!");
				}
			}

			JSONObject ret = new JSONObject();
			ret.getValue().put("id", JSONMapper.toJSON(event.getId()));
			ret.getValue().put("description", JSONMapper.toJSON(event.getDescription()));
			ret.getValue().put("startTime",
					JSONMapper.toJSON(shortFormat.format(event.getStartTime())));
			ret.getValue().put("properStartTime",
					JSONMapper.toJSON(longFormat.format(event.getStartTime())));
			ret.getValue().put("protoStartTime",
					JSONMapper.toJSON(protoFormat.format(event.getStartTime())));
			ret.getValue()
					.put("endTime", JSONMapper.toJSON(shortFormat.format(event.getEndTime())));
			ret.getValue().put("properEndTime",
					JSONMapper.toJSON(longFormat.format(event.getEndTime())));
			ret.getValue().put("protoEndTime",
					JSONMapper.toJSON(protoFormat.format(event.getEndTime())));
			ret.getValue().put("repeated", new JSONBoolean(event.isRepeated()));
			ret.getValue().put("frequency", JSONMapper.toJSON(event.getFrequency()));
			ret.getValue().put("title", JSONMapper.toJSON(event.getTitle()));
			ret.getValue().put("dnr",
					JSONMapper.toJSON(protoFormat.format(event.getDoNotRepeatPast())));
			ret.getValue().put("calid", JSONMapper.toJSON(event.getParent().getId()));
			ret.getValue().put(
					"shortDesc",
					JSONMapper.toJSON(event.getDescription().length() > 25 ? event.getDescription()
							.substring(0, 25) : event.getDescription()));

			Object[] temp = event.getInvites().toArray();
			JSONArray vals = new JSONArray();
			for (int ndx = 0; ndx < temp.length; ndx++)
				vals.getValue().add(JSONMapper.toJSON((Invite) temp[ndx]));
			ret.getValue().put("invites", vals);

			temp = event.getFiles().toArray();
			vals = new JSONArray();
			for (int ndx = 0; ndx < temp.length; ndx++)
				vals.getValue().add(JSONMapper.toJSON((FileAccess) temp[ndx]));

			ret.getValue().put("files", JSONMapper.toJSON(temp));

			Calendar start = Calendar.getInstance();
			start.setTime(event.getStartTime());
			int startSlot = getSlot(start);
			
			Calendar end = Calendar.getInstance();
			end.setTime(event.getEndTime());
			int endSlot = getSlot(end);
			
			int allDays = end.get(Calendar.DAY_OF_YEAR) - start.get(Calendar.DAY_OF_YEAR);
			
			if (startSlot == 0 && endSlot == 47)
				allDays += allDays == 0 ? 1 : 2;
			
			ret.getValue().put("startSlot", JSONMapper.toJSON(startSlot));
			ret.getValue().put("startCol", JSONMapper.toJSON(start.get(Calendar.DAY_OF_WEEK)-1));
			ret.getValue().put("endSlot", JSONMapper.toJSON(endSlot));
			ret.getValue().put("endCol", JSONMapper.toJSON(end.get(Calendar.DAY_OF_WEEK)-1));
			ret.getValue().put("allDays", JSONMapper.toJSON(allDays));
			ret.getValue().put("tinyevent", new JSONBoolean(end.getTimeInMillis() - start.getTimeInMillis() < 15000));
			return ret;
		}

		return null;
	}

	private int getSlot(Calendar time) {
		return Math.min(47, time.get(Calendar.HOUR_OF_DAY) * 2 + (time.get(Calendar.MINUTE) >= 15 ? time
				.get(Calendar.MINUTE) >= 45 ? 2 : 1 : 0));
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Object toJava(JSONValue aValue, Class aRequestedClass) throws MapperException {
		// We won't be using this functionality
		return null;
	}

}
